# -*- coding: utf-8 -*-

import os
import sys
import jinja2
import pytz
import datetime
import openerp
from openerp import tools, api
import simplejson
import werkzeug.utils
from openerp import http
from openerp.http import request
from reportlab.graphics.barcode import createBarcodeDrawing

from openerp.osv import fields, osv
from openerp.addons.wechat.enterprise import WxApi, WxApplication, WxTextResponse, WxNewsResponse, WxArticle, WxLink
from openerp.addons.website_mshop.pools import ModelPool, CursorProxy, common_functions, PageProxy, _slug
ISODATEFORMAT = '%Y-%m-%d'
ISODATETIMEFORMAT = "%Y-%m-%d %H:%M:%S"
SUPERUSER_ID = 1
from openerp.addons.dftg_weixin.application.application_assistant import WxAppCropAssistant

if hasattr(sys, 'frozen'):
    # When running on compiled windows binary, we don't have access to package loader.
    path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'html'))
    loader = jinja2.FileSystemLoader(path)
else:
    loader = jinja2.PackageLoader('openerp.addons.dftg_weixin', "html")

env = jinja2.Environment(block_start_string='<%', block_end_string='%>'
                         , variable_start_string='${', variable_end_string='}'
                         , comment_start_string='{##', comment_end_string='##}'
                         , loader=loader, autoescape=True)
def strftime(str, fmt):
    if isinstance(str, bool):
        return '';
    dt = datetime.datetime.strptime(str, '%Y-%m-%d %H:%M:%S')
    dt = dt.replace(tzinfo=pytz.utc).astimezone(pytz.timezone('Asia/Shanghai'))
    return dt.strftime(fmt.encode('utf-8')).decode('utf-8')

env.filters['strftime'] = strftime



class WorkStockController(http.Controller):
    weixin_app = None

    def __init__(self):
        env.globals['_pool'] = ModelPool()
        env.globals['_cr'] = CursorProxy()
        env.globals['_page'] = PageProxy()
        env.globals['_slug'] = _slug
        env.globals.update(common_functions)
        env.filters['to_json'] = simplejson.dumps
        self.wxapp = WxAppCropAssistant()

    def _parse_int(self, parsed_value):
        try:
            parse_value = int(parsed_value)
        except ValueError:
            # TODO 应该需要返回一个错误的response
            raise osv.except_osv(u'错误', u'遇到一个无法解析的id')

        return parse_value

    #####################################################################
    #
    # 生成二维码
    #
    #####################################################################
    @http.route('/wx/work/qr_or_bar_code', auth='public')
    def weixin_login_qrcode(self, type, value, width=600, height=100):
        """Contoller able to render barcode images thanks to reportlab.
        Samples:
            <img t-att-src="'/report/barcode/QR/%s' % o.name"/>
            <img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' %
                ('QR', o.name, 200, 200)"/>

        :param type: Accepted types: 'Codabar', 'Code11', 'Code128', 'EAN13', 'EAN8', 'Extended39',
        'Extended93', 'FIM', 'I2of5', 'MSI', 'POSTNET', 'QR', 'Standard39', 'Standard93',
        'UPCA', 'USPS_4State'
        """

        try:
            width, height = int(width), int(height)
            if width > 600:
                width = 600
            if height > 600:
                height = 600
            url = "http://" + request.httprequest.host + "/wx/" + value
            barcode = createBarcodeDrawing(
                type, value=url, format='png', width=width, height=height
            )
            barcode = barcode.asString('png')
        except (ValueError, AttributeError):
            raise openerp.exceptions.HTTPException(description='Cannot convert into barcode.')

        return request.make_response(barcode, headers=[('Content-Type', 'image/png')])

    # 取得销售订单剩余可发货数
    def get_so_line_remainder_delivery_qty(self, so_id, context=None):
        cr, context, pool = request.cr, request.context, request.registry
        """ 重置 本次发货数量  并显示可用库存(用以核对) """
        sale_order_obj = pool.get('sale.order')
        sale_order_row = sale_order_obj.browse(cr, SUPERUSER_ID, so_id, context=context)
        product_id_order_dcit = {}
        lines_remainder = {}
        order_lines = []
        all_picking_created = True #全部建立了出库单
        for order_line in sale_order_row.order_line:
            if order_line.product_id.type == 'service':
                continue
            # 计算被保留的产品的数量
            # stock_quant_ids = stock_quant.search(cr, uid, [(
            #     "product_id", "=", order_line.product_id.id), ("reservation_id", "!=", False), ('location_id.usage', '=', 'internal')], context=context)
            # for stock_quant_obj in stock_quant.browse(cr, uid, stock_quant_ids, context=context):
            #     reservation_qty += stock_quant_obj.qty
            product_id_order_dcit.update({order_line.product_id.id: order_line})
            order_lines.append({'id': order_line.id, 'name': order_line.name, 'qty': order_line.product_uom_qty})
        if product_id_order_dcit:
            result_dict = pool.get(
                'product.product').get_product_location_available_qty(cr, SUPERUSER_ID, product_id_order_dcit.keys(),
                                                                      so_id=sale_order_row.id, context=context)
            sale_order_enough_qty = True
            location_ids = sale_order_obj.get_sale_order_location_id(cr, SUPERUSER_ID, sale_order_row.id, context=context)[1]
            for product_id, order_line in product_id_order_dcit.items():
                # 1.订单行数量大于零 则进行 产品库存检查
                # 2. 订单行数量小于零 则 不进行库存检查,直接产品数量 减去 已建发货单数量
                # 1.订单行的产品数量必须 大于零 才会进行计算
                # 2. 的可用数量大于未建出库单 的数量

                #库存可用数
                available_without_reservation = sum([result_dict.get((product_id, order_line.prod_spec or None, location_id),0)
                                                     for location_id in location_ids])
                #本次发货数量
                remainder_delivery_qty = abs(order_line.product_uom_qty) - order_line.delivered_qty
                if remainder_delivery_qty != 0:
                    all_picking_created = False
                lines_remainder.setdefault(order_line.id, {'product_id': order_line.product_id.id,
                                                           'whole_qty': order_line.product_uom_qty, #全部出库数量
                                                           'available_without_reservation': available_without_reservation, #可用库存数
                                                           'remainder_delivery_qty': remainder_delivery_qty,
                                                           'locked_quant_qty': order_line.locked_quant_qty
                                                           }) #剩余建立出库单数量
        return order_lines, lines_remainder, all_picking_created


    #设置picking的送货人员
    @http.route('/wx/api/stock/picking/<int:picking_id>', type='json', methods=['PATCH'], auth='weixin')
    def stock_picking_update(self, picking_id, db=None, agentid=None):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        data = request.jsonrequest
        result = pool.get('stock.picking').write(cr, uid, picking_id, data)
        return {'id': picking_id, 'result': result}

    # 取得json产品库存数
    @http.route('/wx/api/stock/available/sale_order/<int:so_id>', methods=['GET'], auth='weixin')
    def stock_available_qty(self, so_id, db=None, agentid=None):
        cr, context, pool = request.cr, request.context, request.registry
        stock_available_qty = {}
        sale_order_obj = pool.get('sale.order')
        sale_order_row = sale_order_obj.browse(cr, SUPERUSER_ID, so_id, context=context)
        location_ids = sale_order_obj.get_sale_order_location_id(cr, SUPERUSER_ID, so_id, context=context)[1]

        product_id_order_dcit = {}
        for order_line in sale_order_row.order_line:
            if order_line.product_id.type == 'service':
                continue
            product_id_order_dcit.update({order_line.product_id.id: order_line})
        result_dict = pool.get('product.product').get_product_location_available_qty(cr, SUPERUSER_ID,
                                                                                     product_id_order_dcit.keys(),
                                                                                     so_id=so_id,
                                                                                     context=context)
        for product_id, order_line in product_id_order_dcit.items():
            #库存可用数
            available_without_reservation = sum([result_dict.get((product_id, order_line.prod_spec or None, location_id),0)
                                                     for location_id in location_ids])
            stock_available_qty.setdefault(order_line.id, available_without_reservation)
        return simplejson.dumps(stock_available_qty)

    #取得销售订单出库单简单列表
    def get_picking_simple_list(self, so_id, no_done=False):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        states = ['cancel']
        if no_done:
            states.append('done')
        sql = """SELECT sm.picking_id, sp.name, sp.picking_type_id, sp.state,
                 CASE WHEN sp.picking_type_id=2 THEN '出库' ELSE '入库' END AS type,
                 COUNT(*) AS products_count
                 FROM stock_picking sp INNER JOIN stock_move sm ON sp.id=sm.picking_id
                 WHERE sp.so_id=%s AND sp.state NOT IN %s GROUP BY sm.picking_id, sp.name, sp.picking_type_id, sp.state
                 ORDER BY sm.picking_id"""
        cr.execute(sql, (so_id, tuple(states)))
        return cr.dictfetchall()

    # 取得出库单简单列表json
    @http.route('/wx/api/so/<int:so_id>/pickings/list', methods=['GET'], auth='weixin')
    def api_so_picking_list(self, so_id, db=None, agentid=None):
        picking_rows = self.get_picking_simple_list(so_id)
        return simplejson.dumps(picking_rows)


    # 取得出库单保留库存产品数量
    @http.route('/wx/api/stock/pickings/<int:picking_id>/reserve', type='json', methods=['PATCH'], auth='weixin')
    def api_stock_picking_reserve(self, picking_id, db=None, agentid=None):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        stock_picking_obj = pool.get('stock.picking')
        picking_row = stock_picking_obj.browse(cr, uid, picking_id, context=context)
        if picking_row.state == 'draft':
            stock_picking_obj.action_confirm(cr, uid, picking_id, context=context)
        else:
            pass
            #stock_picking_obj.action_assign(cr, uid, picking_id, context=context)
        reserved_availability_lines = {}
        for move_line in picking_row.move_lines:
            reserved_availability_lines.setdefault(move_line.id, int(move_line.reserved_availability))
        return reserved_availability_lines


    # 出库单领取并出库
    @http.route('/wx/api/stock/pickings/<int:picking_id>/pickup', type='json', methods=['PATCH'], auth='weixin')
    def api_stock_picking_pickup(self, picking_id, db=None, agentid=None):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        stock_picking_obj = pool.get('stock.picking')
        result = False
        message = ""
        picking_row = stock_picking_obj.browse(cr, SUPERUSER_ID, picking_id, context=context)
        try:
            #出库移动
            vals = {}
            if picking_row.state == 'cancel':
                return {'id': picking_id, 'user_id': uid, 'message': '已取消不能出库！'}
            if picking_row.state == 'assigned':
                stock_picking_obj.do_enter_transfer_details(
                    cr, SUPERUSER_ID, [picking_id], context=context)
                transfer_details_ids = pool.get('stock.transfer_details').search(
                    cr, SUPERUSER_ID, [('picking_id', '=', picking_id)], context=context)
                # 做真的移动(触发stock.py的action_done)
                pool.get('stock.transfer_details').do_detailed_transfer(
                    cr, SUPERUSER_ID, transfer_details_ids, context=context)
                vals = {'delivery_user_id': uid, 'delivery_start_time': fields.datetime.now()}
            elif picking_row.state == 'done':
                if picking_row.delivery_user_id:
                    if picking_row.delivery_user_id.id == uid:
                        result = True
                    else:
                        message = u"出库单已经被%s领货" % picking_row.delivery_user_id.login
                else:
                    vals = {'delivery_user_id': uid, 'delivery_start_time': fields.datetime.now()}
                    message = u"出库单已经送货完成不能再次领货"
            elif picking_row.state in ('confirmed', 'partially_available'):
                #检查可用库存并锁定
                stock_picking_obj.action_assign(cr, SUPERUSER_ID, picking_id, context=context)
                # 如果锁定成功才能领货
                if stock_picking_obj.browse(cr, SUPERUSER_ID, picking_id, context=context).state == 'assigned':
                    #移动出库
                    return_val = stock_picking_obj.do_enter_transfer_details(
                        cr, SUPERUSER_ID, [picking_id], context=context)
                    # 做真的移动(触发stock.py的action_done)
                    pool.get('stock.transfer_details').do_detailed_transfer(
                        cr, SUPERUSER_ID, return_val.get('res_id'), context=context)
                    #写入领货人
                    vals ={'delivery_user_id': uid, 'delivery_start_time': fields.datetime.now()}
                else:
                    message = u"出库单未锁定库存，无法领货"
            else:
                message = u"出库单未锁定库存，无法领货"
            employee_ids = pool.get('hr.employee').search(cr, uid,  [('user_id', '=', uid)], context=context)
            employee_rows = pool.get('hr.employee').browse(cr, uid, employee_ids, context=context)
            vals.update({'packages_number': request.httprequest.args.get('packages_number', 0),
                         'total_weight_kilo': request.httprequest.args.get('total_weight_kilo', 0)})
            if request.httprequest.args.get('note', False):
                vals.update({'note': request.httprequest.args.get('note')})
            if request.httprequest.args.get('shipping_type_sale', False) and request.httprequest.args.get('shipping_type_sale', False) != 'False':
                vals.update({'shipping_type_sale': request.httprequest.args.get('shipping_type_sale')})
            elif employee_rows:
                if employee_rows[0] and employee_rows[0].department_id.name == u'物流部':
                    vals.update({'shipping_type_sale': 'self_logistics'})
                if employee_rows[0] and employee_rows[0].department_id.name == u'销售部':
                    vals.update({'shipping_type_sale': 'sale_delivery'})
                if employee_rows[0] and employee_rows[0].department_id.name == u'仓储部':
                    vals.update({'shipping_type_sale': 'express_delivery'})
            result = stock_picking_obj.write(cr, SUPERUSER_ID, picking_id, vals)
        except osv.except_osv, e:
            cr.rollback()
            if e.message:
                message = e.message
            else:
                message = ': '.join(map(str, e.args))
        return {'id': picking_id, 'result': result, 'user_id': uid, 'message': message}

    @http.route('/wx/api/stock/pickings/<int:picking_id>/picking', type='json', methods=['PATCH'], auth='weixin')
    def some_one_want_picking(self, picking_id, **kwargs):
        cr, context, pool, uid = request.cr, request.context, request.registry, request.session.uid
        stock_picking_obj = pool.get('stock.picking')
        stock_picking_obj.write(cr, uid, picking_id, {'picking_user_id': uid,
                                                      'picking_start_datetime':
                                                          datetime.datetime.now().strftime(ISODATEFORMAT)},
                                context=context)
        user_row = pool.get('res.users').browse(cr, uid, uid, context=context)
        return {'result': True, 'picking_user_name': user_row.name}

    # 客户已签收
    @http.route('/wx/api/stock/pickings/<int:picking_id>/sign', type='json', methods=['PATCH'], auth='weixin')
    def api_stock_picking_sign(self, picking_id, db=None, agentid=None):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        stock_picking_obj = pool.get('stock.picking')
        result = stock_picking_obj.stock_picking_sign(cr, uid, picking_id, context=None)
        return {'id': picking_id, 'result': result, 'user_id': uid}

    # 保存快递单号
    @http.route('/wx/api/stock/pickings/<int:picking_id>/change_tracking_number', type='json', methods=['PATCH'], auth='weixin')
    def api_stock_picking_change_tracking_number(self, picking_id, db=None, agentid=None):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        stock_picking_obj = pool.get('stock.picking')
        stock_picking_obj.write(cr, uid, picking_id, {'tracking_number':
                                                           simplejson.loads(request.httprequest.args.get('tracking_number'))
                                                       }, context=context)
        return True

    # 建立出库单
    @http.route('/wx/stock/picking', type='json', methods=['POST'], auth='weixin')
    def create_stock_picking(self):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        data = request.jsonrequest
        so_id = data.get('so_id')
        lines_out_qty = data.get('lines_remainder')
        sale_order_obj = pool.get('sale.order')
        confirm_out_going_wizard = pool.get('confirm.out.going.wizard')
        sale_order_row = sale_order_obj.browse(cr, uid, so_id, context=context)[0]
        return_result = {'success': False}
        #如果采购未处理，则提示错误信息
        if not sale_order_row.purchase_managed:
            return_result['error'] = u'采购还未处理完'
            return return_result

        for line in sale_order_row.order_line:
            if lines_out_qty.has_key(str(line.id)):
                delivery_quantity_qty = lines_out_qty[str(line.id)].get('remainder_delivery_qty')
                line.write({'delivery_quantity_qty': delivery_quantity_qty})
        # 暂时不强制有库存才能出库(用js弱检测库存是否足够)
        context.update({'default_sale_order_id': so_id, 'on_move': True})
        try:
            result = confirm_out_going_wizard.confirm_out_going(cr, uid, None, context=context)
            return_result['success'] = True
            return_result['picking_id'] = result.get('res_id')
        except osv.except_osv, e:
            cr.rollback()
            if e.message:
                return_result['error'] = e.message
            else:
                return_result['error'] = e.args
        return return_result

    # 微信理货单查看库存和建立出货单操作
    @http.route('/wx/stock/tally/<int:so_id>', methods=['GET'], auth='weixin')
    def stock_picking_tally(self, so_id, db=None, agentid=None, **kw):
        cr, context, pool = request.cr, request.context, request.registry
        order_lines, lines_remainder, all_picking_created = self.get_so_line_remainder_delivery_qty(so_id)
        #取得其他出库单简单列表
        exists_picking_simple_list = self.get_picking_simple_list(so_id)
        if all_picking_created and len(exists_picking_simple_list) == 1:
            single_picking_id = exists_picking_simple_list[0].get('picking_id')
            if kw.get('from') == 'sale':
                return werkzeug.utils.redirect('/wx/stock/picking_view/' + str(single_picking_id))
            return werkzeug.utils.redirect('/wx/stock/picking_print/' + str(single_picking_id))

        template = env.get_template("stock/tally.html")
        return template.render({
            'so_id': so_id,
            'from': kw.get('from', 'print'),
            'order_lines': order_lines,
            'lines_remainder': lines_remainder,
            'exists_picking_simple_list': exists_picking_simple_list
        })

    # 微信假单理货单页面
    @http.route('/wx/stock/fake/<int:so_id>', methods=['GET'], auth='weixin')
    def stock_fake_redirect_picking(self, so_id, db=None, agentid=None):
        cr, context, pool = request.cr, request.context, request.registry
        order_row = pool.get('sale.order').browse(cr, 1, so_id, context=context)
        if order_row.real_so_id:
            so_id = order_row.real_so_id.id
        order_lines, lines_remainder, all_picking_created = self.get_so_line_remainder_delivery_qty(so_id)
        #取得其他出库单简单列表
        exists_picking_simple_list = self.get_picking_simple_list(so_id, no_done=True)
        if all_picking_created and len(exists_picking_simple_list) >= 1:
            single_picking_id = exists_picking_simple_list[0].get('picking_id')
            return werkzeug.utils.redirect('/wx/stock/picking_view/' + str(single_picking_id))

        template = env.get_template("stock/tally.html")
        return template.render({
            'so_id': so_id,
            'order_lines': order_lines,
            'lines_remainder': lines_remainder,
            'exists_picking_simple_list': exists_picking_simple_list
        })

    # 出库单打印
    @http.route('/wx/stock/picking_print/<int:picking_id>', methods=['GET'], auth='weixin')
    def stock_picking_print(self, picking_id, db=None, agentid=None, **kw):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        picking_obj = pool.get('stock.picking')
        picking_row = picking_obj.browse(cr, SUPERUSER_ID, picking_id, context=context)
        sale_order = picking_row.so_id
        # 取得纸质发票个数
        official_invoice_map = {} #{False: 1L, True: 1L}
        if sale_order.sale_order_invoice:
            cr.execute("SELECT is_outer_invoice, COUNT(*) as invoice_count FROM official_invoice_lines"
                       " WHERE is_invoiced=TRUE AND official_invoice_id=%s GROUP BY is_outer_invoice", (sale_order.sale_order_invoice.id, ))
            official_invoiced_line = cr.dictfetchall()
            for invoiced_line in official_invoiced_line:
                official_invoice_map[invoiced_line.get('is_outer_invoice')] = invoiced_line.get('invoice_count')

        #检查假单
        fake_order_id = pool.get('sale.order').search(cr, uid, [('real_so_id', '=', picking_row.so_id.id)], context=context)

        url_prefix = "http://" + request.httprequest.host

        lodop_host = '192.168.0.10'
        if url_prefix.find('localhost') > 0 or url_prefix.find('tunnel') > 0:
            lodop_host = '127.0.0.1'

        user_row = pool.get('res.users').browse(cr, uid, uid, context=context)
        delivery_user_id = picking_row.delivery_user_id.id
        if not delivery_user_id:
            delivery_user_id = 0
        is_sign = False
        if picking_row.delivery_done_time:
            is_sign = True

        #判断权限
        has_service_manager = pool.get('res.users').user_has_groups(cr, uid,
                                        groups='dftg_product_card.customer_service_manager', context=context)
        data = {
                'fake_order_id': fake_order_id,
                'user_id': uid,
                'from': kw.get('from', 'print'),
                'user_name': user_row.name,
                'picking_user_name': picking_row.picking_user_id and picking_row.picking_user_id.name or '',
                'has_service_manager': has_service_manager,
                'picking_id': picking_id,
                'picking_row': picking_row,
                'sale_order': picking_row.so_id,
                'is_sign': is_sign, #是否签收
                'delivery_user_id': delivery_user_id,
                'delivery_done_time': picking_row.delivery_done_time,
                'official_invoice_map': official_invoice_map,
                'url_prefix': url_prefix,
                'lodop_host': lodop_host,
                'move_lines_map': {}
        }

        #取得销售订单其他相关picking
        if picking_row.so_id:
            #取得其他出库单简单列表
            so_id = picking_row.so_id.id
            other_picking_ids = picking_obj.search(cr, uid, [('so_id', '=', so_id), ('id', '!=', picking_id)], context=context)
            if other_picking_ids:
                other_picking_rows = picking_obj.browse(cr, uid, other_picking_ids, context=context)
                data.update({'other_picking_rows': other_picking_rows})
            #简单列表
            exists_picking_simple_list = self.get_picking_simple_list(so_id)
            data.update({'exists_picking_simple_list': exists_picking_simple_list})
            #取得出库产品map
            move_lines_map = {}
            for move_line in picking_row.move_lines:
                move_lines_map.setdefault(move_line.product_id.id, move_line.product_qty)
            data.update({'move_lines_map': move_lines_map})

        #---- 取得司机、仓储物流人员、采购、销售列表
        #取得司机
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id INNER JOIN hr_job hj ON he.job_id=hj.id WHERE hj.name='司机' AND rr.user_id IS NOT NULL")
        user_list_1 = cr.dictfetchall()
        #取得仓储部非司机人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='仓储部' AND (hj.name<>'司机' OR he.job_id IS NULL) AND rr.user_id IS NOT NULL")
        #取得销售部人员
        user_list_2 = cr.dictfetchall()
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='销售部' AND rr.user_id IS NOT NULL")
        user_list_3 = cr.dictfetchall()
        #取得采购部人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='采购部' AND rr.user_id IS NOT NULL")
        user_list_4 = cr.dictfetchall()
        #取得无部门人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id WHERE he.department_id IS NULL AND rr.user_id IS NOT NULL")
        user_list_5 = cr.dictfetchall()
        user_list = user_list_1 + user_list_2 + user_list_3 + user_list_4 + user_list_5

        data.update({'user_list': user_list})

        template = env.get_template("stock/picking_print.html")
        return template.render(data)

    # 出库单领取操作
    @http.route('/wx/stock/picking_view/<int:picking_id>', methods=['GET'], auth='weixin')
    def stock_picking_view(self, picking_id, db=None, agentid=None, **kw):
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        picking_obj = pool.get('stock.picking')
        picking_row = picking_obj.browse(cr, SUPERUSER_ID, picking_id, context=context)
        sale_order = picking_row.so_id
        # 取得纸质发票个数
        official_invoice_map = {} #{False: 1L, True: 1L}
        if sale_order.sale_order_invoice:
            cr.execute("SELECT is_outer_invoice, COUNT(*) as invoice_count FROM official_invoice_lines"
                       " WHERE is_invoiced=TRUE AND official_invoice_id=%s GROUP BY is_outer_invoice", (sale_order.sale_order_invoice.id, ))
            official_invoiced_line = cr.dictfetchall()
            for invoiced_line in official_invoiced_line:
                official_invoice_map[invoiced_line.get('is_outer_invoice')] = invoiced_line.get('invoice_count')

        url_prefix = "http://" + request.httprequest.host

        lodop_host = '192.168.0.10'
        if url_prefix.find('localhost') > 0 or url_prefix.find('tunnel') > 0:
            lodop_host = '127.0.0.1'

        user_row = pool.get('res.users').browse(cr, uid, uid, context=context)
        delivery_user_id = picking_row.delivery_user_id.id
        if not delivery_user_id:
            delivery_user_id = 0
        is_sign = False
        if picking_row.delivery_done_time:
            is_sign = True
        #判断权限
        has_service_manager = pool.get('res.users').user_has_groups(cr, uid,
                                        groups='dftg_product_card.customer_service_manager', context=context)
        # 在出库单上 显示更改快递出库方式不需要权限判断。（微信扫码查看）
        # employee_ids = pool.get('hr.employee').search(cr, uid, [('user_id', '=', uid), ('department_id.name', '=', '仓储部')], context=context)
        # is_show_note_shipping_type = False
        # if employee_ids:
        #     is_show_note_shipping_type = True
        #
        data = {
                'user_id': uid,
                'packages_number': picking_row.packages_number,
                'total_weight_kilo': picking_row.total_weight_kilo,
                'note': picking_row.note,
                 'from': kw.get('from', 'print'),
                'is_show_note_shipping_type': True,
                'shipping_type_sale': picking_row.shipping_type_sale,
                'user_name': user_row.name,
                'has_service_manager': has_service_manager,
                'picking_id': picking_id,
                'picking_user_name': picking_row.picking_user_id and picking_row.picking_user_id.name or '',
                'picking_row': picking_row,
                'tracking_number': picking_row.tracking_number and\
                                   picking_row.tracking_number.replace('\n', '\\n') or '',
                'sale_order': picking_row.so_id,
                'is_sign': is_sign, #是否签收
                'delivery_user_id': delivery_user_id,
                'delivery_done_time': picking_row.delivery_done_time,
                'official_invoice_map': official_invoice_map,
                'url_prefix': url_prefix,
                'lodop_host': lodop_host}

        #取得销售订单其他相关picking
        if picking_row.so_id:
            #取得其他出库单简单列表
            other_picking_ids = picking_obj.search(cr, uid, [('so_id', '=', sale_order.id), ('id', '!=', picking_id)], context=context)
            if other_picking_ids:
                other_picking_rows = picking_obj.browse(cr, uid, other_picking_ids, context=context)
                data.update({'other_picking_rows': other_picking_rows})
            #简单列表
            exists_picking_simple_list = self.get_picking_simple_list(sale_order.id)
            data.update({'exists_picking_simple_list': exists_picking_simple_list})

        #---- 取得司机、仓储物流人员、采购、销售列表
        #取得司机
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id INNER JOIN hr_job hj ON he.job_id=hj.id WHERE hj.name='司机' AND rr.user_id IS NOT NULL")
        user_list_1 = cr.dictfetchall()
        #取得仓储部非司机人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='仓储部' AND (hj.name<>'司机' OR he.job_id IS NULL) AND rr.user_id IS NOT NULL")
        #取得销售部人员
        user_list_2 = cr.dictfetchall()
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='销售部' AND rr.user_id IS NOT NULL")
        user_list_3 = cr.dictfetchall()
        #取得采购部人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id INNER JOIN hr_department hd ON he.department_id=hd.id WHERE hd.name='采购部' AND rr.user_id IS NOT NULL")
        user_list_4 = cr.dictfetchall()
        #取得无部门人员
        cr.execute("SELECT rr.user_id as value, he.name_related AS title FROM hr_employee he INNER JOIN resource_resource rr ON he.resource_id=rr.id LEFT JOIN hr_job hj ON he.job_id=hj.id WHERE he.department_id IS NULL AND rr.user_id IS NOT NULL")
        user_list_5 = cr.dictfetchall()
        user_list = user_list_1 + user_list_2 + user_list_3 + user_list_4 + user_list_5
        weixin_js_params = self.wxapp.get_jsapi_signature(cr, uid, pool, context)
        data.update({'user_list': user_list})
        data.update(weixin_js_params)
        template = env.get_template("stock/picking_view.html")
        return template.render(data)

    def _generate_image_path(self, file):
        cr, context, pool = request.cr, request.context, request.registry
        direction = pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'dftg_ext.editor_image_folder')
        if direction:
            if not os.path.exists(direction) or not os.path.isdir(direction):
                raise ValueError(u'错误，系统配置中获取到的路径不不是文件夹或不存在')
        else:
            main_direction = tools.config.filestore(cr.dbname)
            img_direction = 'weixin_media'
            first_direction = os.path.join(img_direction, datetime.datetime.now().strftime(ISODATEFORMAT))
            if not os.path.exists(os.path.join(main_direction, first_direction)):
                os.makedirs(os.path.join(main_direction, first_direction))
            filename = os.path.join(first_direction, file)
        return filename, os.path.join(main_direction, filename)
    
    
    @http.route('/wx/stock/upload_pickings_image/<int:picking_id>/<string:MediaId>', type='json', auth='weixin')
    def upload_picture(self, picking_id=[], MediaId='', **kw):
        data = {}
        cr, uid, context, pool = request.cr, request.session.uid, request.context, request.registry
        picking_obj = pool.get('stock.picking')
        if MediaId:
            picking_row = pool.get('stock.picking').browse(cr, uid, picking_id, context=context)
            send_message = True
            if picking_row.picture_list_ids:
                send_message = False
            file_path = self._generate_image_path(MediaId)
            self.wxapp.wxapi.download_media(MediaId, file_path[1])
            list_id = pool.get('picture.list').create(cr, SUPERUSER_ID, {'picking_id': picking_id,
                                                      'image_sign_path': file_path[0]},
                                            context=context)

            picture_list = pool.get('picture.list').browse(cr, SUPERUSER_ID, list_id, context=context)
            if send_message:
                begin_date = (datetime.datetime.now() - datetime.timedelta(days=7)).strftime('%Y-%m-%d %H:%M:%S')
                end_date = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
                picking_not_done_ids = picking_obj.search(cr, uid, [('delivery_start_time', '>=', begin_date),
                                                                    ('delivery_start_time', '<=', end_date),
                                                                    ('is_full_returned', '=', False),
                                                                    ('delivery_user_id', '=', picking_row.delivery_user_id.id),
                                                                    '|', ('delivery_done_time', '=', False),
                                                                    ('state', 'not in', ('done', 'cancel')),
                                                                    ], context=context)
                picking_done_not_picture_ids = picking_obj.search(cr, uid, [('delivery_start_time', '>=', begin_date),
                                                                            ('delivery_start_time', '<=', end_date),
                                                                            ('picture_list_ids', '=', False),
                                                                            ('state', '!=', 'cancel'),
                                                                            ('is_full_returned', '=', False),
                                                                            ('delivery_user_id', '=',
                                                                            picking_row.delivery_user_id.id),
                                                                            ('delivery_done_time', '!=', False),

                                                                            ], context=context)
                (datetime.datetime.now()).strftime('%Y-%m-%d')
                send_message = '%s日消息提醒：已领货未送达%s单' % ((datetime.datetime.now()).strftime('%Y-%m-%d'), len(picking_not_done_ids))
                if picking_not_done_ids:
                    picking_rows = picking_obj.browse(cr, uid, picking_not_done_ids, context=context)
                    send_message = '%s(%s)' % (send_message, '、'.join([picking_row.so_id.name for picking_row in picking_rows]))
                send_message = '%s,已送达未拍照%s单' % (send_message, len(picking_done_not_picture_ids))
                if picking_done_not_picture_ids:
                    not_picture_rows = picking_obj.browse(cr, uid, picking_done_not_picture_ids, context=context)
                    send_message = '%s(%s)' % (send_message, '、'.join([picking_row.so_id.name for picking_row in not_picture_rows]))
                pool.get('sale.order').send_message(cr, uid, picking_row.delivery_user_id.id, send_message, context=context)
            return simplejson.dumps({'image_sign': picture_list.image_sign})

    @http.route('/wx/vue2_test', methods=['GET'])
    def vue2_test(self):
        data = {}
        template = env.get_template("vue2_test.html")
        return template.render(data)
